package com.tmc.service.intair;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.tmc.bean.common.CommonResult;
import com.tmc.bean.common.ContextInfo;
import com.tmc.bean.common.Pagination;
import com.tmc.bean.common.PolicyBean;
import com.tmc.bean.intair.EthFare;
import com.tmc.bean.intair.EthFlight;
import com.tmc.bean.intair.EthSegment;
import com.tmc.bean.intair.EthShoppingReq;
import com.tmc.constant.FareConstant;
import com.tmc.constant.FareConstant.PolicyStatus;
import com.tmc.constant.OrderConstant;
import com.tmc.dao.impl.CommisionPolicyDaoImpl;
import com.tmc.entity.intair.CommisionPolicy;
import com.tmc.entity.intair.IntairFare;
import com.tmc.entity.intair.IntairFlight;
import com.tmc.entity.intair.IntairOrder;
import com.tmc.entity.intair.IntairPassenger;
import com.tmc.entity.intair.IntairSegment;
import com.tmc.service.baseinfo.AirlineServiceImpl;
import com.tmc.service.baseinfo.AirportServiceImpl;
import com.tmc.service.baseinfo.ContinentServiceImpl;
import com.tmc.service.baseinfo.CountryServiceImpl;
import com.tmc.util.DateUtil;
import com.tmc.util.ObjectUtil;
import com.tmc.util.PolicyMatchUtil;
import com.tmc.util.PolicyUtil;

@Service
@Transactional
public class CommisionPolicyServiceImpl {

	private Log logger = LogFactory.getLog(CommisionPolicyServiceImpl.class);
	
	@Autowired
	private CommisionPolicyDaoImpl policyDao;

	@Autowired
	private CountryServiceImpl countrySer;

	@Autowired
	private ContinentServiceImpl continentSer;

	@Autowired
	private AirportServiceImpl airportSer;

	@Autowired
	private AirlineServiceImpl airlineSer;
	
	@Autowired
	private IntairOrderServiceImpl orderService;
	

	public Pagination<CommisionPolicy> findPolicysByCon(ContextInfo context, CommisionPolicy cond, int pageIndex,
			int pageSize) {
		Pagination<CommisionPolicy> result = policyDao.findPolicysByCon(context, cond, pageIndex, pageSize);
		this.setExtInfo(result);
		return result;
	}

	public CommisionPolicy getById(ContextInfo context, Long policyId) {
		return policyDao.getById(policyId);
	}

	public CommonResult changePolicyStatus(ContextInfo context, Long policyId, String toStatus) {
		CommisionPolicy policy = policyDao.getById(policyId);
		if (policy != null) {
			ObjectUtil.updateBaseInfo(policy, context);
			policy.setStatus(toStatus);
			policyDao.update(policy);
		}
		return CommonResult.makeSuccess();
	}

	public CommonResult changePolicysStatus(ContextInfo context, String policyIds, String toStatus) {
		if (ObjectUtil.noText(policyIds)) {
			return CommonResult.makeFail("请选择至少一条政策");
		}
		for (String policyId : policyIds.split(",")) {
			this.changePolicyStatus(context, Long.valueOf(policyId), toStatus);
		}
		return CommonResult.makeSuccess();
	}

	public CommonResult deletePolicy(ContextInfo context, Long policyId) {
		CommisionPolicy policy = policyDao.getById(policyId);
		if (policy != null) {
			ObjectUtil.updateBaseInfo(policy, context);
			policy.setEnabledFlag("N");
			policyDao.update(policy);
		}
		return CommonResult.makeSuccess("删除成功！");
	}

	public CommonResult deletePolicys(ContextInfo context, String policyIds) {
		if (!ObjectUtil.hasText(policyIds)) {
			return CommonResult.makeFail("请至少选择一条数据！");
		}
		for (String str : policyIds.split(",")) {
			CommonResult cr = this.deletePolicy(context, Long.valueOf(str));
			if (!cr.isSuccess()) {
				return cr;
			}
		}
		return CommonResult.makeSuccess("删除成功！");
	}
	
	public CommisionPolicy copyPolicy(ContextInfo context, Long policyId) {
		CommisionPolicy dbPolicy = policyDao.getById(policyId);
		CommisionPolicy policy = new CommisionPolicy();
		try {
			if(dbPolicy != null){
				ObjectUtil.copyProperties(dbPolicy,policy,
						new String[] { "createdBy", "creationDate", "status", "policyId", "enabledFlag" });
			}
			policy.setSourcePolicyId(dbPolicy.getPolicyId());
			this.beforeShow(policy);
		} catch (Exception e) {
			logger.error("复制政策失败！", e);
		}
		return policy;
	}

	public CommisionPolicy getById4Show(ContextInfo context, Long policyId) {
		CommisionPolicy policy = policyDao.getById(policyId);
		CommisionPolicy result = ObjectUtil.makeTargetBean(policy, CommisionPolicy.class);
		this.beforeShow(result);
		return result;
	}
	
	public void beforeShow(List<CommisionPolicy> policys) {
		if(policys == null || policys.isEmpty()){
			return;
		}
		for (CommisionPolicy policy : policys) {
			beforeShow(policy);
		}
	}

	public void beforeShow(CommisionPolicy policy) {
		if(policy == null){
			return;
		}
		policy.setFlightTypeName(PolicyUtil.getFlightTypeName(policy.getFlightType()));
		policy.setDepartureName(this.getAreaNames(policy.getDeparture()));
		policy.setArrivalName(this.getAreaNames(policy.getArrival()));
		policy.setAirlineName(airlineSer.getNameByCode(policy.getAirline().toUpperCase()));
		policy.setStatusName(FareConstant.getStatusName(policy.getStatus()));
		policy.setAutoTicketingFlagName(PolicyUtil.getTrueOrFalseName(policy.getAutoTicketingFlag()));
		try {
			policy.setOutboundTravelDateStartStr(DateUtil.toStrDate(policy.getOutboundTravelDateStart(), "yyyy-MM-dd"));
			policy.setOutboundTravelDateEndStr(DateUtil.toStrDate(policy.getOutboundTravelDateEnd(), "yyyy-MM-dd"));
			policy.setInboundTravelDateStartStr(DateUtil.toStrDate(policy.getInboundTravelDateStart(), "yyyy-MM-dd"));
			policy.setInboundTravelDateEndStr(DateUtil.toStrDate(policy.getInboundTravelDateEnd(), "yyyy-MM-dd"));
			policy.setTicketingDateStartStr(DateUtil.toStrDate(policy.getTicketingDateStart(), "yyyy-MM-dd"));
			policy.setTicketingDateEndStr(DateUtil.toStrDate(policy.getTicketingDateEnd(), "yyyy-MM-dd"));
			if(policy.getOutboundTravelDateExcludeStart() != null){
				policy.setOutboundTravelDateExcludeStartStr(DateUtil.toStrDate(policy.getOutboundTravelDateExcludeStart(), "yyyy-MM-dd"));
			}
			if(policy.getOutboundTravelDateExcludeEnd() != null){
				policy.setOutboundTravelDateExcludeEndStr(DateUtil.toStrDate(policy.getOutboundTravelDateExcludeEnd(), "yyyy-MM-dd"));
			}
		} catch (ParseException e) {
		}
		policy.setTicketTypeStr(PolicyUtil.getTicketTypeStr(policy.getTicketType()));
		policy.setChildStr(PolicyUtil.getChildStr(policy));
		policy.setChildExtStr(PolicyUtil.getChildExtStr(policy));
		policy.setInfantStr(PolicyUtil.getInfantStr(policy.getInfant()));
		policy.setInfantExtStr(PolicyUtil.getInfantExtStr(policy));
		policy.setEligibilityExcludeStr(PolicyUtil.getEligibilityExcludeStr(policy.getEligibilityExclude()));
		policy.setTravelerCountsExtStr(PolicyUtil.getTravelerCountsExtStr(policy.getTravelerCountsExt()));
		policy.setCombinationStr(PolicyUtil.getCombinationStr(policy));
		
		//设置显示信息
		StringBuilder memoExtStr = new StringBuilder();
		memoExtStr.append("[票本类型:]" + policy.getTicketTypeStr() + "<br>");
		memoExtStr.append("[去程有效期:]" + policy.getOutboundTravelDateStartStr() + "至"
				+ policy.getOutboundTravelDateEndStr() + "<br>");
		memoExtStr.append(ObjectUtil.hasText(policy.getInboundTravelDateStartStr()) ? "[回程有效期:]"
				+ policy.getInboundTravelDateStartStr() + "至" + policy.getInboundTravelDateEndStr() + "<br>" : "");
		memoExtStr.append("[儿童票:]" + policy.getChildStr() + " "
				+ (ObjectUtil.hasText(policy.getChildExtStr()) ? policy.getChildExtStr() + "<br>" : "<br>"));
		memoExtStr.append("[婴儿票:]" + policy.getInfantStr() + " "
				+ (ObjectUtil.hasText(policy.getInfantExtStr()) ? policy.getInfantExtStr() + "<br>" : "<br>"));
		memoExtStr.append(ObjectUtil.hasText(policy.getEligibilityExcludeStr())
				? "[不适用:]" + policy.getEligibilityExcludeStr() + "<br>" : "");
		memoExtStr.append((policy.getTravelerCountsStart() != null && policy.getTravelerCountsStart() >= 0
				&& policy.getTravelerCountsEnd() != null && policy.getTravelerCountsEnd() > 0)
				|| ObjectUtil.hasText(policy.getTravelerCountsExt()) ? "[适用人数:]" : "");
		memoExtStr.append(policy.getTravelerCountsStart() != null && policy.getTravelerCountsStart() >= 0
				&& policy.getTravelerCountsEnd() != null && policy.getTravelerCountsEnd() > 0
						? policy.getTravelerCountsStart() + "-" + policy.getTravelerCountsEnd() + " " : "");
		memoExtStr.append(
				ObjectUtil.hasText(policy.getTravelerCountsExtStr()) ? policy.getTravelerCountsExtStr() + "<br>" : "");
		memoExtStr.append(policy.getAgeStart() != null && policy.getAgeStart() >= 0 && policy.getAgeEnd() != null
				&& policy.getAgeEnd() > 0 ? "[适用年龄:]" + policy.getAgeStart() + "-" + policy.getAgeEnd() + "<br>" : "");
		memoExtStr.append("[指定Office号订位:]" + policy.getOfficeNo() + "<br>");
		memoExtStr.append(ObjectUtil.hasText(policy.getCombinationStr()) ? policy.getCombinationStr() + "<br>" : "");
		memoExtStr.append(ObjectUtil.hasText(policy.getOutboundFlight())
				? "[去程适用航班:]" + policy.getOutboundFlight() + "<br>" : "");
		memoExtStr.append(
				ObjectUtil.hasText(policy.getInboundFlight()) ? "[回程适用航班:]" + policy.getInboundFlight() + "<br>" : "");
		memoExtStr.append(
				ObjectUtil.hasText(policy.getFlightExclude()) ? "[不适用航班:]" + policy.getFlightExclude() + "<br>" : "");
		memoExtStr.append(
				ObjectUtil.hasText(policy.getLineExclude()) ? "[不适用航线:]" + policy.getLineExclude() + "<br>" : "");
		memoExtStr.append(ObjectUtil.hasText(policy.getOutboundTravelDateExcludeStartStr())
				&& ObjectUtil.hasText(policy.getOutboundTravelDateExcludeEndStr())
						? "[去程不适用日期:]" + policy.getOutboundTravelDateExcludeEndStr() + "至"
								+ policy.getOutboundTravelDateExcludeStartStr() + "<br>"
						: "");
		memoExtStr.append(ObjectUtil.hasText(policy.getMemo()) ? "[其他备注:]" + policy.getMemo() + "<br>" : "");
		policy.setMemoExt(memoExtStr.toString());
	}

	private String getAreaNames(String areas) {
		if (ObjectUtil.noText(areas)) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		for (String area : areas.split("/")) {
			if (ObjectUtil.noText(area)) {
				continue;
			}
			String areaName = this.getAreaName(area);
			if (sb.indexOf(areaName + "/") > -1){
				continue;
			}
			sb.append(areaName).append("/");
		}
		return sb.toString();
	}

	private String getAreaName(String area) {
		if ("CN0".equals(area)) {
			return "中国境内";
		}
		if ("CN1".equals(area)) {
			return "境外";
		}
		if ("A00".equals(area)) {
			return "全球";
		}
		if (area.length() == 2) {
			return countrySer.getNameByCode(area);
		}
		if (area.length() == 3) {
			return airportSer.getCityNameByCode(area);
		}
		if (area.length() == 4) {
			return continentSer.getNameByCode(area);
		}
		return area;
	}

	public List<CommisionPolicy> findPolicys(ContextInfo context, EthShoppingReq req) {
		try {
			List<CommisionPolicy> policys = policyDao.findPolicys(context, req);
			return policys;
			//return filterPolicys(context, policys, req);
		} catch (Exception e) {
 			logger.error(e.getMessage());
			return null;
		}
	}

	/*
	 * private List<CommisionPolicy> filterPolicys(ContextInfo context,
	 * List<CommisionPolicy> policys, EthShoppingReq req) {
	 * List<CommisionPolicy> result = new ArrayList<CommisionPolicy>();
	 * 
	 * for (CommisionPolicy policy : policys) { if (!isMatch(policy, req)) {
	 * continue; } result.add(policy); }
	 * 
	 * return result; }
	 */
	/*
	 * private boolean isMatch(CommisionPolicy policy, EthShoppingReq req) { //
	 * 去程旅行日期 // 格式：YYYY-MM-DD>YYYY-MM-DD，多个用“/”隔开，为空表示不限制
	 * if(!isDateMatch(policy.getOutboundTravelDate(), req.getDepartureDate()))
	 * { return false; } // 回城旅行日期 if ("RT".equals(req.getFlightType()) &&
	 * !isDateMatch(policy.getInnboundTravelDate(), req.getReturnDate())) {
	 * return false; } // 销售日期是否匹配 if (!isDateMatch(policy.getSalesDate(),
	 * DateUtil.toStrDate(new Date(), DateUtil.yyyy_MM_dd))) { return false; }
	 * // 出发地除外 if (ObjectUtil.hasText(policy.getDepartureExceptCitys()) &&
	 * policy.getDepartureExceptCitys().indexOf("/" + req.getDeparture()) > -1)
	 * { return false; } // 目的地除外 if
	 * (ObjectUtil.hasText(policy.getArrivalExceptCitys()) &&
	 * policy.getArrivalExceptCitys().indexOf("/" + req.getArrival()) > -1) {
	 * return false; } return true; }
	 */

	/*
	 * private boolean isDateMatch(String policyDate, String reqDate) { Long
	 * departDate = DateUtil.toLongDate(reqDate, DateUtil.yyyy_MM_dd); if
	 * (ObjectUtil.noText(policyDate)) { return true; } for (String range :
	 * policyDate.split("/")) { if (isRangeMatch(range, departDate)) { return
	 * true; } } return false; }
	 */

	/*
	 * private boolean isRangeMatch(String range, Long departDate) { if
	 * (ObjectUtil.noText(range)) { return false; } String[] strs =
	 * range.split(">"); Long begin = DateUtil.toLongDate(strs[0],
	 * DateUtil.yyyy_MM_dd); Long end = DateUtil.toLongDate(strs[1],
	 * DateUtil.yyyy_MM_dd); if (departDate >= begin && departDate <= end) {
	 * return true; } return false; }
	 */

	public CommonResult savePolicy(ContextInfo context, CommisionPolicy policy) {
		//
		CommonResult check = this.checkPolicy(context, policy);
		if (!check.isSuccess()) {
			return check;
		}
		// 处理字段
		this.beforeSave(policy);
		// 保存
		if (policy.getPolicyId() == null) {
			try {
				ObjectUtil.setBaseInfo(policy, context);
				policy.setStatus(PolicyStatus.DOWN.getStatus());
				policyDao.insert(policy);
			} catch (Exception e) {
				logger.error("保存政策失败！", e);
				return CommonResult.makeFail(e.getMessage());
			}
		} else { // 编辑
			try {
				CommisionPolicy dbPolicy = policyDao.getById(policy.getPolicyId());
				if (dbPolicy != null) {
					ObjectUtil.copyProperties(policy, dbPolicy,
							new String[] { "createdBy", "creationDate", "status", "policyId", "enabledFlag" });
				}
				ObjectUtil.updateBaseInfo(dbPolicy, context);
				policyDao.update(dbPolicy);
			} catch (Exception e) {
				logger.error("保存政策失败！", e);
				return CommonResult.makeFail("保存政策失败！");
			}
		}
		return CommonResult.makeSuccess();

	}
	
	private CommonResult checkPolicy(ContextInfo context, CommisionPolicy policy) {
		
		return CommonResult.makeSuccess();
	}

	private void beforeSave(CommisionPolicy policy) {
		if (!"Y".equals(policy.getAutoTicketingFlag())){
			policy.setAutoTicketingFlag("N");
		}
		if (!"Y".equals(policy.getBaseCommisionFlag())){
			policy.setBaseCommisionFlag("N");
		}
		policy.setOutboundTravelDateStart(DateUtil.toLongDate(policy.getOutboundTravelDateStartStr(), "yyyy-MM-dd"));
		policy.setOutboundTravelDateEnd(DateUtil.toLongDate(policy.getOutboundTravelDateEndStr(), "yyyy-MM-dd"));
		policy.setInboundTravelDateStart(DateUtil.toLongDate(policy.getInboundTravelDateStartStr(), "yyyy-MM-dd"));
		policy.setInboundTravelDateEnd(DateUtil.toLongDate(policy.getInboundTravelDateEndStr(), "yyyy-MM-dd"));
		policy.setTicketingDateStart(DateUtil.toLongDate(policy.getTicketingDateStartStr(), "yyyy-MM-dd"));
		policy.setTicketingDateEnd(DateUtil.toLongDate(policy.getTicketingDateEndStr(), "yyyy-MM-dd"));
		if(ObjectUtil.hasText(policy.getOutboundTravelDateExcludeStartStr())){
			policy.setOutboundTravelDateExcludeStart(DateUtil.toLongDate(policy.getOutboundTravelDateExcludeStartStr(), "yyyy-MM-dd"));
		}
		if(ObjectUtil.hasText(policy.getOutboundTravelDateExcludeEndStr())){
			policy.setOutboundTravelDateExcludeEnd(DateUtil.toLongDate(policy.getOutboundTravelDateExcludeEndStr(), "yyyy-MM-dd"));
		}
		policy.setDeparture(getSpecialArea(policy.getDeparture()));
		policy.setArrival(getSpecialArea(policy.getArrival()));
		policy.setTransfer(getSpecialArea(policy.getTransfer()));
	}
	
	private String getSpecialArea(String area) {
		return area.replace("中国境内", "CN0").replace("境外", "CN1").replace("全球", "A00");
	}

	private void setExtInfo(Pagination<CommisionPolicy> result) {
		if (result == null || result.getItems() == null || result.getItems().isEmpty()) {
			return;
		}
		for (CommisionPolicy policy : result.getItems()) {
			this.beforeShow(policy);
		}
	}

	public CommonResult matchNativePolicy(ContextInfo context,Long orderId){
		IntairOrder dbOrder = orderService.getById(context, orderId);
		if(dbOrder == null){
			return CommonResult.makeFail("订单出错!");
		}
		CommisionPolicy cond = new CommisionPolicy();
		if(!this.setSearchCond(cond, dbOrder)){
			return CommonResult.makeFail("未匹配到政策");
		}
		
		List<CommisionPolicy> policys = new ArrayList<CommisionPolicy>();//返回结果
		if (dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_RT)) {// 往返订单
			List<CommisionPolicy> dbPolicysRT = policyDao.findListByPolicy(context, cond);			
			this.isMatchRtPolicys(dbOrder, policys, dbPolicysRT);//匹配往返订单的政策
		} else {// 单程  
			//匹配单程的订单
			List<CommisionPolicy> dbPolicysOW = policyDao.findListByPolicy(context, cond);
			for (CommisionPolicy dbPolicy : dbPolicysOW) {
				// 匹配主逻辑
				if (isMatch(dbOrder, dbPolicy)) {
					beforeShow(dbPolicy);
					CommisionPolicy policy = this.calculatePriceInfo(dbPolicy);
					this.calculateCommision(dbOrder, policy);
					policys.add(policy);
				}
			}
		}
		this.sortPolicys(policys);
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("order", dbOrder);
		map.put("showPolicies", policys);
		return CommonResult.makeSuccess("", map);
	}
	
	private boolean setSearchCond(CommisionPolicy policy, IntairOrder dbOrder){
		//匹配单程或往返
		if(ObjectUtil.noText(dbOrder.getFlightType()) || 
				dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_UN) ||
					dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_MU)){
			return false;
		}else{
			policy.setFlightType(dbOrder.getFlightType().equals(OrderConstant.FLIGHT_TYPE_OW) ? "OW":"RT");
		}
		//匹配office号
		policy.setOfficeNo(dbOrder.getOfficeNo());
		//匹配出票方式
		policy.setAutoTicketingFlag(dbOrder.getTicketingType() == 1 ? "Y":"N");
		//政策状态为  UP
		policy.setStatus(PolicyStatus.UP.getStatus());
		return true;
	}
	
	private void sortPolicys(List<CommisionPolicy> policys) {
		if (policys == null || policys.isEmpty()) {
			return;
		}
		Collections.sort(policys, new Comparator<CommisionPolicy>() {
			@Override
			public int compare(CommisionPolicy c1, CommisionPolicy c2) {
				if (c1.getAdtPolicy().getTotalAmount() < c2.getAdtPolicy().getTotalAmount()) {
					return -1;
				} else if (c1.getAdtPolicy().getTotalAmount() > c2.getAdtPolicy().getTotalAmount()) {
					return 1;
				}
				return 0;
			}
		});
	}
	
	private void isMatchRtPolicys(IntairOrder order, List<CommisionPolicy> policys, List<CommisionPolicy> policysRT) {
		List<CommisionPolicy> policysHalfRT = new ArrayList<CommisionPolicy>();
		this.setPolicysRT2PolicysHalfRT(policysRT, policysHalfRT);//初始化允许1/2RT混舱政策集合
		for(CommisionPolicy dbPolicy : policysRT){
			//匹配不允许1/2RT混舱主逻辑
			if (isMatch( order,dbPolicy)) {
				this.beforeShow(dbPolicy);
				CommisionPolicy policy=this.calculatePriceInfo(dbPolicy);
				this.calculateCommision(order,policy);
				policys.add(policy);
			}	
		}
		this.isMatchHalfRtPolicys(order, policys, policysHalfRT);//匹配允许1/2RT混舱主逻辑
	}
	
	private void isMatchHalfRtPolicys(IntairOrder order, List<CommisionPolicy> policys,
			List<CommisionPolicy> policysHalfRT) {
		//匹配1/2RT混舱
		List<CommisionPolicy> policysTo = new ArrayList<CommisionPolicy>();
		List<CommisionPolicy> policysReturn = new ArrayList<CommisionPolicy>();
		
		for (CommisionPolicy policy : policysHalfRT) {
			if(isMatch(policy, order, order.getFlights().get(0))){
				policysTo.add(policy);
			}
			if(isMatch(policy, order, order.getFlights().get(1))){
				policysReturn.add(policy);
			}
		}
		for(CommisionPolicy  policyTo : policysTo){
			for (CommisionPolicy policyReturn : policysReturn) {
				CommisionPolicy policy = new CommisionPolicy();				
				if(policyTo.getPolicyId() != policyReturn.getPolicyId()){
					boolean flag = true;
					for (CommisionPolicy commisionPolicy : policys) {
						if(ObjectUtil.hasText(commisionPolicy.getPolicyIds()) && commisionPolicy.getPolicyIds().contains(policyTo.getPolicyId()+"")
								&& commisionPolicy.getPolicyIds().contains(policyReturn.getPolicyId()+"")){
							flag = false;
						}
					}
					if(flag){
						beforeShow(policyTo);
						beforeShow(policyReturn);
						policy = this.calculatePriceInfo(policyTo, policyReturn);
						this.calculateCommision(order, policy);
						policys.add(policy);
					}
				}else{
					beforeShow(policyTo);
					policy=this.calculatePriceInfo(policyTo);
					this.calculateCommision(order, policy);
					policys.add(policy);
				}
			}
		}			
	}

	private void setPolicysRT2PolicysHalfRT(List<CommisionPolicy> policysRT, List<CommisionPolicy> policysHalfRT) {
		for(int i = 0; i < policysRT.size(); i++){
			CommisionPolicy dbPolicy = policysRT.get(i);
			if (ObjectUtil.hasText(dbPolicy.getCombination()) && dbPolicy.getCombination().equals("Y")) {//允许1/2RT混舱
				policysHalfRT.add(dbPolicy);
				policysRT.remove(dbPolicy);
				i--;
			}	
		}		
	}

	/**
	 * 给匹配好的政策计算出不同类型乘客的价格信息
	 * 
	 * @param dbPolicys
	 * @return policy
	 */
	public CommisionPolicy calculatePriceInfo(List<CommisionPolicy> dbPolicys){
		
		if(dbPolicys == null || dbPolicys.isEmpty()){
			return new CommisionPolicy();
		}
		if(dbPolicys.size() == 1){
			return calculatePriceInfo(dbPolicys.get(0));
		}else{
			return calculatePriceInfo(dbPolicys.get(0), dbPolicys.get(1));
		}
	}
	

	/**
	 * 不是混舱1/2RT计算价格信息(对应一条政策)
	 * @param dbPolicy
	 * @return policy
	 */
	
	public CommisionPolicy calculatePriceInfo(CommisionPolicy dbPolicy) {
		CommisionPolicy policy = new CommisionPolicy();
		
		if(dbPolicy == null){
			return policy;
		}
		//设置备注信息
		policy.setMemoExt(dbPolicy.getMemoExt());
		//设置政策Ids
		policy.setPolicyIds(dbPolicy.getPolicyId()+"");
		// 设置成人信息
		policy.setCommision(dbPolicy.getCommision());
		policy.setReward(dbPolicy.getReward());
		policy.setTicketingPrice(dbPolicy.getTicketingPrice() == null ? 0D : dbPolicy.getTicketingPrice());
		policy.setRtOff(dbPolicy.getRtOff() == null? 0d : dbPolicy.getRtOff());
		policy.setOwOff(dbPolicy.getOwOff() == null? 0d : dbPolicy.getOwOff());
		// 儿童信息
		// 儿童代理费
		if (ObjectUtil.hasText(dbPolicy.getChildExt()) && dbPolicy.getChildExt().contains("2")) {
			policy.setChdCommision(0D);
		} else {
			policy.setChdCommision(dbPolicy.getCommision());
		}
		// 儿童奖励
		if (dbPolicy.getChild().equals("1")) {
			policy.setChdReward(dbPolicy.getReward());
		} else if (dbPolicy.getChild().equals("4")) {
			policy.setChdReward((dbPolicy.getChdReward() == null ? 0D : dbPolicy.getChdReward()));
		} else {
			policy.setChdReward(0D);
		}
		// 儿童加手开票手续费
		if (ObjectUtil.hasText(dbPolicy.getChildExt()) && dbPolicy.getChildExt().contains("1")) {
			policy.setChdTicketingPrice((dbPolicy.getTicketingPrice() == null ? 0D : dbPolicy.getTicketingPrice())
					+ (dbPolicy.getChdServicePrice() == null ? 0D : dbPolicy.getChdServicePrice()));
		} else {
			policy.setChdTicketingPrice((dbPolicy.getTicketingPrice() == null ? 0D : dbPolicy.getTicketingPrice()));
		}
		//儿童直减
		if(ObjectUtil.hasText(dbPolicy.getChildExt()) && dbPolicy.getChildExt().contains("4")){
			policy.setChdRtOff(policy.getRtOff());
			policy.setChdOwOff(policy.getOwOff());
		}else{
			policy.setChdRtOff(0d);
			policy.setChdOwOff(0d);
		}
		// 婴儿信息
		// 婴儿代理费
		policy.setInfCommision(dbPolicy.getCommision());
		// 婴儿奖励
		policy.setInfReward(0D);
		policy.setInfTicketingPrice(null);
		// 婴儿加手开票手续费
		if (ObjectUtil.hasText(dbPolicy.getInfantExt()) && dbPolicy.getInfantExt().contains("1")) {
			policy.setInfTicketingPrice((dbPolicy.getTicketingPrice() == null ? 0D : dbPolicy.getTicketingPrice())
					+ (dbPolicy.getInfServicePrice() == null ? 0D : dbPolicy.getInfServicePrice()));
		} else {
			policy.setInfTicketingPrice((dbPolicy.getTicketingPrice() == null ? 0D : dbPolicy.getTicketingPrice()));
		}
		//婴儿直减
		policy.setInfRtOff(policy.getRtOff());
		policy.setInfOwOff(policy.getOwOff());
		return policy;
	}
	

	/**
	 * 
	 * 不是混舱1/2RT计算价格信息(对应一条政策)
	 * 
	 * @param dbPolicyTo
	 * @param dbPolicyReturn
	 * @return
	 */
	public CommisionPolicy calculatePriceInfo(CommisionPolicy dbPolicyTo, CommisionPolicy dbPolicyReturn){
		CommisionPolicy policy = new CommisionPolicy();
		
		if(dbPolicyTo == null || dbPolicyReturn == null ){
			return policy;
		}
		// 设置备注信息
		policy.setMemoExt(dbPolicyTo.getMemoExt() + "<hr>" + dbPolicyReturn.getMemoExt());
		// 设置政策Ids
		policy.setPolicyIds(dbPolicyTo.getPolicyId() + "," + dbPolicyReturn.getPolicyId());
		// 去和返的正常开票费
		Double ticketingPriceTo = dbPolicyTo.getTicketingPrice() == null ? 0D : dbPolicyTo.getTicketingPrice();
		Double ticketingPriceReturn = dbPolicyReturn.getTicketingPrice() == null ? 0D
				: dbPolicyReturn.getTicketingPrice();
		
		// 设置成人信息
		policy.setCommision(ObjectUtil.getDouble2Decimal((dbPolicyTo.getCommision() + dbPolicyReturn.getCommision()) / 2));
		policy.setReward(ObjectUtil.getDouble2Decimal((dbPolicyTo.getReward() + dbPolicyReturn.getReward()) / 2));
		policy.setTicketingPrice(ticketingPriceTo > ticketingPriceReturn ? ticketingPriceTo : ticketingPriceReturn);
		// 当有两条政策的情况下 一定是往返订单
		policy.setRtOff(ObjectUtil.getDouble2Decimal(((dbPolicyTo.getRtOff() == null ? 0d : dbPolicyTo.getRtOff())
				+ (dbPolicyReturn.getRtOff() == null ? 0d : dbPolicyReturn.getRtOff())) / 2));
		policy.setOwOff(ObjectUtil.getDouble2Decimal(((dbPolicyTo.getOwOff() == null ? 0d : dbPolicyTo.getOwOff())
				+ (dbPolicyReturn.getOwOff() == null ? 0d : dbPolicyReturn.getOwOff())) / 2));

		// 儿童信息
		// 儿童奖励
		if (dbPolicyTo.getChild().equals("2") || dbPolicyReturn.getChild().equals("2")) {
			policy.setChdReward(0D);
		} else if (dbPolicyTo.getChild().equals("1") && dbPolicyReturn.getChild().equals("1")) {
			policy.setChdReward(ObjectUtil.getDouble2Decimal((dbPolicyTo.getReward() + dbPolicyReturn.getReward()) / 2));
		} else if (dbPolicyTo.getChild().equals("1") && dbPolicyReturn.getChild().equals("4")) {
			double reward = dbPolicyTo
					.getReward() > (dbPolicyReturn.getChdReward() == null ? 0D : dbPolicyReturn.getChdReward())
							? (dbPolicyReturn.getChdReward() == null ? 0D : dbPolicyReturn.getChdReward())
							: dbPolicyTo.getReward();
			policy.setChdReward(reward);
		} else if (dbPolicyTo.getChild().equals("4") && dbPolicyReturn.getChild().equals("1")) {
			double reward = dbPolicyReturn
					.getReward() > (dbPolicyTo.getChdReward() == null ? 0D : dbPolicyTo.getChdReward())
							? (dbPolicyTo.getChdReward() == null ? 0D : dbPolicyTo.getChdReward())
							: dbPolicyReturn.getReward();
			policy.setChdReward(reward);
		} else {// policyTo.getChild().equals("4") &&
				// policyReturn.getChild().equals("4")
			double reward = (dbPolicyTo.getChdReward() == null ? 0D
					: dbPolicyTo.getChdReward()) > (dbPolicyReturn.getChdReward() == null ? 0D
							: dbPolicyReturn.getChdReward())
									? (dbPolicyReturn.getChdReward() == null ? 0D : dbPolicyReturn.getChdReward())
									: (dbPolicyTo.getChdReward() == null ? 0D : dbPolicyTo.getChdReward());
			policy.setChdReward(reward);
		}
		// 儿童代理费
		if ((ObjectUtil.hasText(dbPolicyTo.getChildExt()) && dbPolicyTo.getChildExt().contains("2"))
				|| (ObjectUtil.hasText(dbPolicyReturn.getChildExt()) && dbPolicyReturn.getChildExt().contains("2"))) {
			policy.setChdCommision(0D);
		} else {
			policy.setChdCommision(ObjectUtil.getDouble2Decimal((dbPolicyTo.getCommision() + dbPolicyReturn.getCommision()) / 2));
		}
		// 儿童开票费
		ticketingPriceTo=0d;
		ticketingPriceReturn=0d;
		if (ObjectUtil.hasText(dbPolicyTo.getChildExt()) && dbPolicyTo.getChildExt().contains("1")) {
			ticketingPriceTo = ticketingPriceTo
					+ (dbPolicyTo.getChdServicePrice() == null ? 0D : dbPolicyTo.getChdServicePrice());
		}
		if (ObjectUtil.hasText(dbPolicyReturn.getChildExt()) && dbPolicyReturn.getChildExt().contains("1")) {
			ticketingPriceReturn = ticketingPriceReturn
					+ (dbPolicyReturn.getChdServicePrice() == null ? 0D : dbPolicyReturn.getChdServicePrice());
		}
		policy.setChdTicketingPrice(ticketingPriceTo > ticketingPriceReturn ? ticketingPriceTo : ticketingPriceReturn);
		// 儿童直减
		if (ObjectUtil.hasText(dbPolicyTo.getChildExt()) && dbPolicyTo.getChildExt().contains("4")
				|| ObjectUtil.hasText(dbPolicyReturn.getChildExt()) && dbPolicyReturn.getChildExt().contains("4")) {
			policy.setChdOwOff(0d);
			policy.setChdRtOff(0d);
		} else {
			policy.setChdOwOff(policy.getOwOff());
			policy.setChdRtOff(policy.getRtOff());
		}
		// 婴儿代理费
		policy.setInfCommision(ObjectUtil.getDouble2Decimal((dbPolicyTo.getCommision() + dbPolicyReturn.getCommision()) / 2));
		// 婴儿奖励
		policy.setInfReward(0D);
		// 婴儿开票费
		if (ObjectUtil.hasText(dbPolicyTo.getInfantExt()) && dbPolicyTo.getInfantExt().contains("1")) {
			ticketingPriceTo = ticketingPriceTo
					+ (dbPolicyTo.getInfServicePrice() == null ? 0D : dbPolicyTo.getInfServicePrice());
		}
		if (ObjectUtil.hasText(dbPolicyReturn.getInfantExt()) && dbPolicyReturn.getInfantExt().contains("1")) {
			ticketingPriceReturn = ticketingPriceReturn
					+ (dbPolicyReturn.getInfServicePrice() == null ? 0D : dbPolicyReturn.getInfServicePrice());
		}
		policy.setInfTicketingPrice(ticketingPriceTo > ticketingPriceReturn ? ticketingPriceTo : ticketingPriceReturn);
		// 婴儿直减
		policy.setInfRtOff(policy.getRtOff());
		policy.setInfOwOff(policy.getOwOff());
		return policy;
	}
	
	/**
	 * 根据订单和匹配的政策计算佣金
	 * @param order
	 * @param policy
	 */
	private void calculateCommision(IntairOrder order, CommisionPolicy policy){	
		//设置政策id
		if(ObjectUtil.hasText(order.getTicketType()) && order.getTicketType().equals(OrderConstant.TICKET_TYPE_B2B)){
			policy.setTicketTypeStr("B2B");
		}else if(ObjectUtil.hasText(order.getTicketType()) && order.getTicketType().equals(OrderConstant.TICKET_TYPE_BSP)){
			policy.setTicketTypeStr("BSP");
		}else{
			policy.setTicketTypeStr("境外电子");
		}
		PolicyBean adtPolicy = new PolicyBean();
		PolicyBean chdPolicy = null;
		PolicyBean infPolicy = null;
		Double tax = 0d;
		Double ticketPrice = 0d;
		//获取公布运价和税费
		if(order.getPassengers().get(0).getFare() != null){
			IntairFare fare = order.getPassengers().get(0).getFare();
			tax = fare.getTax() == null ? 0d : fare.getTax();
			ticketPrice = fare.getTicketPrice() == null ? 0d:fare.getTicketPrice();
		}
		
		for (IntairPassenger passenger : order.getPassengers()) {
			if("CHD".equals(passenger.getPassengerType())){
				chdPolicy = new PolicyBean();
			}
			if("INF".equals(passenger.getPassengerType())){
				infPolicy = new PolicyBean();
			}
		}
		//设置成人的价格信息
		adtPolicy.setTax(tax);
		adtPolicy.setTicketPrice(ticketPrice);
		adtPolicy.setCommision(policy.getCommision());
		adtPolicy.setReward(policy.getReward());
		adtPolicy.setTicketingPrice(policy.getTicketingPrice()== null? 0d : policy.getTicketingPrice());
		//直减
		Double adtOff = order.getFlightType().equals(OrderConstant.FLIGHT_TYPE_OW) ? (policy.getOwOff() == null ? 0d:policy.getOwOff()):(policy.getRtOff() == null ? 0d:policy.getRtOff());
		adtPolicy.setOff(adtOff);
		//返点和奖励
		Double adtComRew = Math.ceil(ticketPrice * adtPolicy.getCommision() * 0.01)
				+ Math.ceil(ticketPrice * adtPolicy.getReward() * 0.01);
		adtPolicy.setTotalAmount(ticketPrice + tax - adtComRew + adtPolicy.getTicketingPrice() - adtOff );
		
		if(chdPolicy != null){
			chdPolicy.setTax(tax);
			chdPolicy.setTicketPrice(ticketPrice);
			chdPolicy.setCommision(policy.getChdCommision());
			chdPolicy.setReward(policy.getChdReward());
			chdPolicy.setTicketingPrice(policy.getChdTicketingPrice() == null? 0d : policy.getChdTicketingPrice());
			//直减
			Double chdOff = order.getFlightType().equals(OrderConstant.FLIGHT_TYPE_OW) ? (policy.getChdOwOff() == null ? 0d:policy.getChdOwOff()):(policy.getChdRtOff() == null ? 0d:policy.getChdRtOff());
			chdPolicy.setOff(chdOff);
			//返点和奖励
			Double chdComRew = Math.ceil(ticketPrice * chdPolicy.getCommision() * 0.01)
					+ Math.ceil(ticketPrice * chdPolicy.getReward() * 0.01);
			chdPolicy.setTotalAmount(ticketPrice + tax - chdComRew + chdPolicy.getTicketingPrice() -chdOff );
		}
		if(infPolicy != null){
			infPolicy.setTax(tax);
			infPolicy.setTicketPrice(ticketPrice);
			infPolicy.setCommision(policy.getInfCommision());
			infPolicy.setReward(policy.getInfReward());
			infPolicy.setTicketingPrice(policy.getInfTicketingPrice() == null? 0d : policy.getInfTicketingPrice());
			//直减
			Double infOff = order.getFlightType().equals(OrderConstant.FLIGHT_TYPE_OW) ? (policy.getInfOwOff() == null ? 0d:policy.getInfOwOff()):(policy.getInfRtOff() == null ? 0d:policy.getInfRtOff());
			infPolicy.setOff(infOff);
			//返点和奖励
			Double infComRew = Math.ceil(ticketPrice * infPolicy.getCommision() * 0.01)
					+ Math.ceil(ticketPrice * infPolicy.getReward() * 0.01);
			infPolicy.setTotalAmount(ticketPrice + tax - infComRew +infPolicy.getTicketingPrice() - infOff); 
		}
		
		//设置显示价格的信息
		policy.setAdtPolicy(adtPolicy);
		policy.setChdPolicy(chdPolicy);
		policy.setInfPolicy(infPolicy);
		
		
		// //设置显示信息
		// policy.setTax(tax);
		// policy.setTicketPrice(ticketPrice);
		// //设置结算价
		// Double commision = policy.getCommision();
		// policy.setCommision(commision);
		// Double reward = policy.getReward();
		// policy.setReward(reward);
		// Double ticketingPrice = policy.getTicketingPrice() == null ? 0d :
		// policy.getTicketingPrice();//开票费
		// policy.setTicketingPrice(ticketingPrice);
		// //直减
		// Double off =
		// order.getFlightType().equals(OrderConstant.FLIGHT_TYPE_OW) ?
		// (policy.getOwOff() == null ? 0d:policy.getOwOff()):policy.getRtOff()
		// == null ? 0d:policy.getRtOff();
		// policy.setOff(off);
		// Double comRew = Math.ceil(ticketPrice * commision * 0.01)
		// + Math.ceil(ticketPrice * reward * 0.01);
		// policy.setTotalAmount(ticketPrice +tax -comRew + ticketingPrice - off
		// + tax);
	}
	
	private boolean isMatch(IntairOrder order, CommisionPolicy policy){
		if(order == null || policy == null){
			return false;
		}
		String flightType = "OW";
		if(order.getFlights().size()>1){
			flightType = "RT";
		}
		if(flightType.equals("RT")){
			if(!isMatch(policy, order, order.getFlights().get(0))){
				return false;
			}
			if(!isMatch(policy, order, order.getFlights().get(1))){
				return false;
			}
			return true;
		}else{
			return isMatch(policy, order, order.getFlights().get(0));
		}
	}
	
	private boolean isMatch(CommisionPolicy policy, IntairOrder order, IntairFlight flight){
		//相关时间是否匹配
		if(!PolicyMatchUtil.isDateMatch(policy, order, flight)){
			return false;
		}
		
		// 中转地是否匹配
		if (!PolicyMatchUtil.isTransferMatch(flight.getTransfer(),
				airportSer.getCountryCodeByCode(flight.getTransfer()), policy.getTransfer(),
				policy.getTransferExclude())) {// 匹配中转地
			return false;
		}
		if (order.getFlights().get(0) == flight) {// 去程
			// 匹配去程的出发地和到达地位
			if (!PolicyMatchUtil.isDirectMatch(flight.getDeparture(),
					airportSer.getCountryCodeByCode(flight.getDeparture()), flight.getArrival(),
					airportSer.getCountryCodeByCode(flight.getArrival()), policy)) {//
				return false;
			} 
			// 匹配去程的舱位
			if (!PolicyMatchUtil.isCabinMatch(flight, policy.getDepartureCabins(), policy.getTransferCabins())) {
				return false;
			}
			
					
		} else { // 返程
			// 匹配返程的出发地和到达地位
			if (!PolicyMatchUtil.isDirectMatch(flight.getArrival(),
					airportSer.getCountryCodeByCode(flight.getArrival()), flight.getDeparture(),
					airportSer.getCountryCodeByCode(flight.getDeparture()), policy)) {//
				return false;
			}
			// 匹配返程的舱位
			if (!PolicyMatchUtil.isCabinMatch(flight, policy.getTransferCabins(), policy.getDepartureCabins())) {
				return false;
			}
		}
		for(IntairSegment segment :flight.getSegments()){
			// 匹配去程适用的航班和航线
			if (!PolicyMatchUtil.isflightNoMatch(segment.getAirline(), segment.getFlightNo(), policy)) {
				return false;
			}
			if(!PolicyMatchUtil.isflightLineMatch(segment.getDeparture(), segment.getArrival(), policy.getLineExclude())){
				return false;
			}
			// 航司是否匹配
			if(!PolicyMatchUtil.isAirlineMatch(segment.getAirline(), policy.getAirline(), policy.getAirlineShare())){
				return false;
			}
		}
		
		// 匹配乘客等信息
		if (!isPassengerMatch(order, policy)) {
			return false;
		}
		return true;
	}

	private boolean isPassengerMatch(IntairOrder order, CommisionPolicy policy) {
		//匹配乘客人数
		if ((policy.getTravelerCountsStart() != null && policy.getTravelerCountsStart() > 0)
				&& policy.getTravelerCountsStart() > order.getPassengers().size()) {
			return false;
		}
		if ((policy.getTravelerCountsEnd() != null && policy.getTravelerCountsEnd() > 0)
				&& policy.getTravelerCountsEnd() < order.getPassengers().size()) {
			return false;
		}
		//TODO travelerCountsExt此条件未完成匹配
		if (ObjectUtil.hasText(policy.getTravelerCountsExt()) && policy.getTravelerCountsExt().contains("Y")
				&& !(order.getPassengers().size() % 2 == 0)) {
			return false;
		}
		for (IntairPassenger passenger : order.getPassengers()) {
//			if (ObjectUtil.noText(passenger.getBirthday())) {
//				return false;
//			}
			//TODO 匹配证件类型  匹配还未完成
			if (ObjectUtil.hasText(policy.getEligibilityExclude())) {
				String cardType =  "";
				if(ObjectUtil.hasText(passenger.getCardType())){
					if (passenger.getCardType().equals(OrderConstant.CARD_TYPE_XUESHENGZHENG)) {
						cardType = "A";
					}
					if (passenger.getCardType().equals(OrderConstant.CARD_TYPE_GANGAOTONGXINGZHENG)
							|| passenger.getCardType().equals(OrderConstant.CARD_TYPE_TAIBAOZHENG)
							|| passenger.getCardType().equals(OrderConstant.CARD_TYPE_TAIWANTONGXINGZHENG)
							|| passenger.getCardType().equals(OrderConstant.CARD_TYPE_HUIXIANGZHENG)) {
						cardType = "T";
					}
				}
				if (ObjectUtil.hasText(cardType) && policy.getEligibilityExclude().contains(cardType)) {
					return false;
				}
			}
			//匹配年龄 和儿童票、婴儿票是否可开,还有票价
			try {
				int psgAge = 0;
				if(ObjectUtil.hasText(passenger.getBirthday())){
					psgAge = DateUtil.getAge(DateUtil.format(passenger.getBirthday()));
				}else{ // 乘客没有生日信息时，当作成人处理
					//TODO
					psgAge=18;
				}
					
				if ((policy.getAgeStart() != null && policy.getAgeStart() >= 0) && policy.getAgeStart() > psgAge) {
					return false;
				}
				if ((policy.getAgeEnd() != null && policy.getAgeEnd() > 0) && policy.getAgeEnd() < psgAge) {
					return false;
				}
				if (psgAge < 2 && ObjectUtil.hasText(policy.getInfant()) && policy.getInfant().equals(2)) {// 匹配婴儿票是否可开
					return false;
				} 
				if (psgAge >= 2 && psgAge < 12) {
					if (ObjectUtil.hasText(policy.getChild()) && policy.getChild().equals(3)) {// 匹配儿童票是否可开
						return false;
					}
				}
				//匹配票价
				if(policy.getTicketPriceLimitStart() !=null && passenger.getFare() != null &&
						policy.getTicketPriceLimitStart() > passenger.getFare().getTotalAmount()){
					return false;
				}
				if(policy.getTicketPriceLimitEnd() !=null && passenger.getFare() != null &&
						policy.getTicketPriceLimitEnd() < passenger.getFare().getTotalAmount()){
					return false;
				}
			} catch (Exception e1) {		
			}
		}
		return true;
	}


	public List<EthFare> matchPolicy(List<EthFare> fares, List<CommisionPolicy> policys) {
		logger.error(new Date() + "匹配policy开始");
		if (policys == null || policys.isEmpty() || fares == null || fares.isEmpty()){
			return fares;
		}
		for (EthFare fare : fares) {
			this.isMatch(fare, policys); // 匹配政策
//			for (CommisionPolicy policy : policys) { 
//				if(!this.isMatch(fare, policy)) {// 是否匹配到政策 
//					continue;
//				} 
//				this.calculateCommision(fare, policy);// 计算运价
//			}
		}
		logger.error(new Date() + "匹配policy结束");
		return fares;
	}
	
	private EthFare isMatch(EthFare fare, List<CommisionPolicy> policys) {
		if (policys == null || policys.isEmpty() || fare == null ){
			return fare;
		}
		String flightType = "OW";
		if (fare.getFlights().size() > 1) {
			flightType = "RT";
		}
		if(flightType.equals("RT")){//匹配往返
			this.isMatchRtPolicys(fare, policys);
		}else{//匹配单程
			for (CommisionPolicy dbPolicy : policys) { 
				if(!this.isMatch(fare, dbPolicy)) {// 是否匹配到政策 
					continue;
				}
				//this.calculateCommisionByDbPolicy(policy, dbPolicy);
				CommisionPolicy policy = this.calculatePriceInfo(dbPolicy);
				this.calculateCommision(fare, policy);// 计算运价
			}
		}
		return fare;
	}
	
	private EthFare isMatchRtPolicys(EthFare fare, List<CommisionPolicy> policys) {
		if (fare == null || policys == null || policys.isEmpty()) {
			return fare;
		}
		List<CommisionPolicy> policysRT = new ArrayList<>();
		List<CommisionPolicy> policysHalfRT = new ArrayList<>();
		// 组装集合
		for (CommisionPolicy policy : policys) {
			if (!policy.getFlightType().contains("RT")) {
				continue;
			}
			// 适用RT
			if (ObjectUtil.hasText(policy.getCombination()) && policy.getCombination().equals("Y")) {// 允许1/2RT混舱
				policysHalfRT.add(policy); // 适用1/2RT
			} else {
				policysRT.add(policy); // 只适用RT
			}
		}
		for (CommisionPolicy dbPolicy : policysRT) {
			if (!this.isMatch(fare, dbPolicy)) {// 是否匹配到政策
				continue;
			}
			//this.calculateCommisionByDbPolicy(policy, dbPolicy);//存放计算价格
			CommisionPolicy policy = this.calculatePriceInfo(dbPolicy);
			this.calculateCommision(fare, policy);// 计算运价
		}
		this.isMatchHalfRtPolicys(fare, policysHalfRT);
		return fare;

	}

	private EthFare isMatchHalfRtPolicys(EthFare fare, List<CommisionPolicy> policysHalfRT) {
		if (fare == null || policysHalfRT == null || policysHalfRT.isEmpty()) {
			return fare;
		}
		// 匹配1/2RT混舱
		List<CommisionPolicy> policysTo = new ArrayList<CommisionPolicy>();
		List<CommisionPolicy> policysReturn = new ArrayList<CommisionPolicy>();
		for (CommisionPolicy policy : policysHalfRT) {
			if (isMatch(policy, fare, fare.getFlights().get(0))) {
				policysTo.add(policy);
			}
			if (isMatch(policy, fare, fare.getFlights().get(1))) {
				policysReturn.add(policy);
			}
		}
		//计算价格信息
		for (CommisionPolicy policyTo : policysTo) {
			for (CommisionPolicy policyReturn : policysReturn) {
				CommisionPolicy policy = null;//存放计算价格的信息
				if (policyTo.getPolicyId() != policyReturn.getPolicyId()) {
					//this.calculateCommisionByDbPolicy(policy, policyTo, policyReturn);
					policy = this.calculatePriceInfo(policyTo, policyReturn);
				} else {
					//this.calculateCommisionByDbPolicy(policy, policyTo);
					policy = this.calculatePriceInfo(policyTo);
				}
				this.calculateCommision(fare, policy);
			}
		}
		return fare;
	}

	
	// 匹配主逻辑
	private boolean isMatch(EthFare fare, CommisionPolicy policy) {
		if (fare == null || policy == null) {
			return false;
		}
		String flightType = "OW";
		if (fare.getFlights().size() > 1) {
			flightType = "RT";
		}
		if (flightType.equals("RT")) {
			if (!isMatch(policy, fare, fare.getFlights().get(0))) {
				return false;
			}
			if (!isMatch(policy, fare, fare.getFlights().get(1))) {
				return false;
			}
			return true;
		} else {
			return isMatch(policy, fare, fare.getFlights().get(0));
		}
	}

	//匹配主逻辑
	private boolean isMatch(CommisionPolicy policy, EthFare fare, EthFlight flight) {
		// 相关时间是否匹配
		if(!PolicyMatchUtil.isDateMatch(policy, fare, flight)){
			return false;
		}
		
		//出票航司是否匹配
		if(PolicyMatchUtil.isAirlineMatch(fare.getTicketingCarrier(), policy.getAirline(), policy.getAirlineShare()))
		if(flight.getSegments().size() > 1){
			return false;
		}
		// 中转地是否匹配
		if (!PolicyMatchUtil.isTransferMatch(flight.getTransfer(),
				airportSer.getCountryCodeByCode(flight.getTransfer()), policy.getTransfer(),
				policy.getTransferExclude())) {// 匹配中转地
			return false;
		}
		if (fare.getFlights().get(0) == flight) {// 去程
			// 匹配去程的出发地和到达地位
			if (!PolicyMatchUtil.isDirectMatch(flight.getDeparture(),
					airportSer.getCountryCodeByCode(flight.getDeparture()), flight.getArrival(),
					airportSer.getCountryCodeByCode(flight.getArrival()), policy)) {//
				return false;
			}
			// 匹配去程的舱位
			if (!PolicyMatchUtil.isCabinMatch(flight, policy.getDepartureCabins(), policy.getTransferCabins())) {
				return false;
			}
			
					
		} else { // 返程
			// 匹配返程的出发地和到达地位
			if (!PolicyMatchUtil.isDirectMatch(flight.getArrival(),
					airportSer.getCountryCodeByCode(flight.getArrival()), flight.getDeparture(),
					airportSer.getCountryCodeByCode(flight.getDeparture()), policy)) {//
				return false;
			}
			// 匹配返程的舱位
			if (!PolicyMatchUtil.isCabinMatch(flight, policy.getTransferCabins(), policy.getDepartureCabins())) {
				return false;
			}
		}
		for(EthSegment segment :flight.getSegments()){
			// 匹配去程适用的航班和航线
			if (!PolicyMatchUtil.isflightNoMatch(segment.getAirline(), segment.getFlightNo(), policy)) {
				return false;
			}
			if(!PolicyMatchUtil.isflightLineMatch(segment.getDeparture(), segment.getArrival(), policy.getLineExclude())){
				return false;
			}
			// 航司是否匹配
			if(!PolicyMatchUtil.isAirlineMatch(segment.getAirline(), policy.getAirline(), policy.getAirlineShare())){
				return false;
			}
		}
		return true;
	}

	public void calculateCommision(EthFare fare, CommisionPolicy policy) {
		Double ticketPrice = fare.getTicketPrice(); 
		Double q = fare.getQ();
		Double commision = policy.getCommision();
		Double settleProfit = policy.getSettleProfit() == null ? 0 : policy.getSettleProfit();
		Double policyCommision = ticketPrice * (commision - settleProfit) / 100 ; 
		if (policyCommision > (fare.getCommisionPrice() ==  null? 0D : fare.getCommisionPrice())) {//后返
			fare.setCommisionPrice(policyCommision);
			fare.setSettleProfit((int) Math.ceil(ticketPrice * settleProfit));
			fare.setSearchTicketPrice(Math.ceil(ticketPrice + q - policyCommision));
			//fare.setCommisionPolicyId(policy.getPolicyId());
			fare.setCommisionPolicyIds(policy.getPolicyIds());
			fare.setCommision(commision);
			fare.setTotalAmount(fare.getSearchTicketPrice() + fare.getTax());
		} 
	}


	/*
	 * // 匹配主逻辑 private boolean isMatch(EthFare fare, CommisionPolicy policy) {
	 * // 航司是否匹配 if (!this.isAirlineMatch(fare, policy)) return false; // 舱位是否匹配
	 * if (!this.isCabinMatch(fare, policy)) return false; // 中转地是否匹配 if
	 * (!this.isTransferMatch(fare, policy)) { return false; } // 出票时限
	 * 
	 * // 代码共享
	 * 
	 * // return true; }
	 

	/*
	 * private boolean isTransferMatch(EthFare fare, CommisionPolicy policy) {
	 * String transferType = "OW"; if (fare.getFlights().size() > 1) {
	 * transferType = "RT"; } if (ObjectUtil.hasText(policy.getTransferType())
	 * && !policy.getTransferType().contains(transferType)) { return false; }
	 * String policyTransferPoint = policy.getTransferPoint(); if
	 * (ObjectUtil.noText(policyTransferPoint)) { return true; } for (EthFlight
	 * flight : fare.getFlights()) { String transferPoint =
	 * flight.getTransferCity(); if (ObjectUtil.hasText(transferPoint) &&
	 * !policyTransferPoint.contains(transferPoint)) { return false; } } return
	 * true; }
	 */

	/*
	 * private boolean isCabinMatch(EthFare fare, CommisionPolicy policy) {
	 * String policyCabin = policy.getCabin(); String cabin =
	 * fare.getBookingCode(); if (policyCabin == null || "".equals(policyCabin))
	 * return true; String[] fareCabins = cabin.split("/"); for (String
	 * fareCabin : fareCabins) { if (!policyCabin.contains(fareCabin)) return
	 * false; } return true; }
	 * 
	 * private boolean isAirlineMatch(EthFare fare, CommisionPolicy policy) {
	 * String ticketingAirline = fare.getTicketingCarrier(); String
	 * policyAirline = policy.getTicketingAirline(); if (policyAirline == null
	 * || "".equals(policyAirline)) return true; if
	 * (policyAirline.equalsIgnoreCase(ticketingAirline)) return true; // 联运航司
	 * if ("Y".equals(policy.getIsInterlineApplicable()) &&
	 * ObjectUtil.hasText(policy.getInterlineAirline()) &&
	 * policy.getInterlineAirline().contains(ticketingAirline) &&
	 * !policy.getInterlineAirlineExcept().contains(ticketingAirline)) { return
	 * true; } return false; }
	 */

	/*
	 * public void calculateCommision(EthFare fare, CommisionPolicy policy) {
	 * Double ticketPrice = fare.getTicketPrice(); Double q = fare.getQ();
	 * Double commision = policy.getCommision();// % Integer settleProfit =
	 * policy.getSettleProfit() == null ? 0 : policy.getSettleProfit();// 留钱 //
	 * 留点留钱 Double policyCommision = ticketPrice * commision / 100 -
	 * settleProfit; if (policyCommision > fare.getCommision()) {
	 * fare.setCommisionPrice(policyCommision);
	 * fare.setSettleProfit(settleProfit);
	 * fare.setSearchTicketPrice(Math.ceil(ticketPrice + q - policyCommision));
	 * fare.setCommisionPolicyId(policy.getPolicyId());
	 * fare.setCommision(commision);
	 * fare.setTotalPrice(fare.getSearchTicketPrice() + fare.getTax()); } }
	 * 
	 * public CommonResult importPolicyFile(ContextInfo context, File file)
	 * throws Exception { String fileName = file.getName().substring(14);
	 * String[][] data = null; if (fileName.endsWith(".xls")) { data =
	 * ExcelUtil.read(file, 1); } else if (fileName.endsWith(".xlsx")) { data =
	 * ExcelUtil.read(file, 1); } else { throw new Exception("不支持的文件类型"); } int
	 * line = 2; for (String[] strs : data) { if (strs.length < 37) { throw new
	 * Exception(fileName + "文件列数少于37，请检查！"); } CommisionPolicy policy = new
	 * CommisionPolicy(); policy.setTourCode(strs[1]);
	 * policy.setCombinableTourCode(strs[2]); policy.setFlightType(strs[3]);
	 * policy.setTicketingAirline(strs[4]); policy.setDepartureArea(strs[5]);
	 * policy.setArrivalArea(strs[6]); policy.setDepartureAreaExcept(strs[7]);
	 * policy.setArrivalAreaExcept(strs[8]); policy.setCabin(strs[9]);
	 * policy.setIsInterlineApplicable(strs[10]);
	 * policy.setInterlineAirline(strs[11]);
	 * policy.setInterlineAirlineExcept(strs[12]);
	 * policy.setTransferType(strs[13]); policy.setTransferPoint(strs[14]);
	 * policy.setIsCodeShare(strs[15]); policy.setIsOpening(strs[16]);
	 * policy.setFareType(strs[17]); policy.setInvoiceType(strs[18]);
	 * policy.setOutboundTravelDate(strs[19]);
	 * policy.setInnboundTravelDate(strs[20]); policy.setSalesDate(strs[21]);
	 * policy.setPassengerType(strs[22]); policy.setEligibility(strs[23]);
	 * policy.setCommision(Double.valueOf(strs[24]));
	 * policy.setSettleProfit(Integer.valueOf(strs[25]));
	 * policy.setTicketingRemark(strs[26]); policy.setWorkingTime(strs[27]);
	 * policy.setNationality(strs[28]); policy.setExcludeNationality(strs[29]);
	 * policy.setCommisionCalculation(strs[30]);
	 * policy.setTicketingDeadline(strs[31]); policy.setTicketingCity(strs[32]);
	 * policy.setIsPrivate(strs[33]);
	 * policy.setPenalties(Double.valueOf(strs[34]));
	 * policy.setIsForSmallGroup(strs[35]);
	 * policy.setIsForFilePubFare(strs[36]); CommonResult result =
	 * this.savePolicy(context, policy); if (!result.isSuccess()) { throw new
	 * Exception(fileName + "文件第" + line + "行有错误，" + result.getMessage()); }
	 * line++; } return CommonResult.makeSuccess(); }
	 * 
	 * private CommonResult checkPolicy(ContextInfo context, CommisionPolicy
	 * policy) { if (ObjectUtil.hasText(policy.getTourCode()) &&
	 * ObjectUtil.noText(policy.getCombinableTourCode())) { return
	 * CommonResult.makeFail("如果文件编号有值，则可组文件编号必须也要有值！"); } if
	 * (!ObjectUtil.inArray(policy.getFlightType(), new String[] { "单程", "往返",
	 * "OW", "RT" })) { return CommonResult.makeFail("单程、往返选其一，也可以为空默认全部！"); }
	 * if (ObjectUtil.noText(policy.getTicketingAirline()) ||
	 * policy.getTicketingAirline().length() != 2) { return
	 * CommonResult.makeFail("出票航司二字码不能为空，且只能录入一家！"); } CommonResult check1 =
	 * this.checkArea(policy.getDepartureArea()); if (!check1.isSuccess()) {
	 * return check1; } CommonResult check2 =
	 * this.checkArea(policy.getArrivalArea()); if (!check2.isSuccess()) {
	 * return check2; } CommonResult check3 =
	 * this.checkArea(policy.getDepartureAreaExcept()); if (!check3.isSuccess())
	 * { return check3; } CommonResult check4 =
	 * this.checkArea(policy.getDepartureAreaExcept()); if (!check4.isSuccess())
	 * { return check4; } if (!ObjectUtil.inArray(policy.getTransferType(), new
	 * String[] { "是", "否", "不限", "True", "False", "UnLimited" })) { return
	 * CommonResult.makeFail("是否适用于中转格式不正确, 是：只适用于中转,否：只适用于直飞,不限：直飞/中转均适用！"); }
	 * if (!ObjectUtil.inArray(policy.getIsCodeShare(), new String[] { "是", "否",
	 * "不限", "True", "False", "UnLimited" })) { return CommonResult.
	 * makeFail("是否适用于代码共享航班格式不正确, 是：只适用共享航班，否：只适用非共享航班，不限：所有航班都适用！"); } if
	 * (!ObjectUtil.inArray(policy.getIsOpening(), new String[] { "是", "否",
	 * "不限", "True", "False", "UnLimited" })) { return
	 * CommonResult.makeFail("是否允许缺口格式不正确, 是：只允许缺口，否：只允许非缺口，不限：缺口/非缺口都适用！"); }
	 * if (!ObjectUtil.inArray(policy.getFareType(), new String[] { "BSP",
	 * "Amadeus" })) { return CommonResult.makeFail("运价类型格式不正确, BSP或Amadeus！");
	 * } if (!ObjectUtil.inArray(policy.getInvoiceType(), new String[] { "旅游发票",
	 * "行程单", "Itinerary", "TravelInvoice" })) { return
	 * CommonResult.makeFail("报销凭证格式不正确, 旅游发票或行程单！"); } if
	 * (ObjectUtil.noText(policy.getSalesDate())) { return
	 * CommonResult.makeFail("销售日期格式不正确, 格式2014-11-01>2015-06-01，只允许录入一个！"); }
	 * if (policy.getCommision() == null) { return
	 * CommonResult.makeFail("返点格式不正确！"); } if (policy.getSettleProfit() ==
	 * null) { policy.setSettleProfit(0); } if
	 * (!ObjectUtil.inArray(policy.getCommisionCalculation(), new String[] {
	 * "各取各", "取严", "TakeStrict", "TakeSelf" })) { return
	 * CommonResult.makeFail("1/2RT佣金计算方式格式不正确！单选：各取各 或 取严！"); } if
	 * (!ObjectUtil.inArray(policy.getIsPrivate(), new String[] { "是", "否",
	 * "True", "False" })) { return CommonResult.makeFail("是否公布转私有格式不正确！"); } if
	 * (!ObjectUtil.inArray(policy.getIsForSmallGroup(), new String[] { "是",
	 * "否", "不限", "True", "False", "UnLimited" })) { return
	 * CommonResult.makeFail("是否适用小团价格式不正确, 是：只适用小团价，否：不适用小团价，不限：不限制运价！"); } if
	 * (!ObjectUtil.inArray(policy.getIsForFilePubFare(), new String[] { "是",
	 * "否", "不限", "True", "False", "UnLimited" })) { return CommonResult.
	 * makeFail("是否适用文件公布运价格式不正确, 是：只适用文件公布运价，否：不适用文件公布运价，不限：不限制运价！"); } //
	 * 校验重复政策 if (policy.getPolicyId() == null) { List<CommisionPolicy> policys
	 * = policyDao.findPolicysByCon(context, policy); if (policys != null &&
	 * !policys.isEmpty()) { return CommonResult.makeFail("已存在相同政策数据，ID为" +
	 * policys.get(0).getPolicyId()); } } return CommonResult.makeSuccess(); }
	 */

	/*
	 * private CommonResult checkArea(String area) { if
	 * (ObjectUtil.noText(area)) { return CommonResult.makeSuccess(); } String[]
	 * strs = area.split("/"); for (String str : strs) { if (str.length() != 2
	 * && str.length() != 3 && str.length() != 4) { return
	 * CommonResult.makeFail(
	 * "地区可录入格式：1.城市三代  如SHA/NYC/SEL 2.国家二代  如CN/US/KR 3.大区四代  如SEAS/JPKR/NAME 4.TC区代码  如TC1/TC2/TC3 5.为空 表示不限制 ， 允许1.2.3.4混合录入，可录入多个用/隔开表示多个最多允许录入100个"
	 * ); } } return CommonResult.makeSuccess(); }
	 * 
	 * @Value("${export_path}") private String export_path;
	 * 
	 * public static String[] headers = new String[] { "外部编号", "文件编号", "可组文件编号",
	 * "行程类型", "开票航司", "出发地", "目的地", "出发地除外", "目的地除外", "适用舱位", "是否适用于联运",
	 * "适用联运航司", "除外联运航司", "是否适用于中转", "指定转机点", "是否适用于代码共享航班", "是否允许缺口", "运价类型",
	 * "报销凭证", "去程旅行日期", "回程旅行日期", "销售日期", "乘客类型", "旅客资质", "返点", "留钱", "出票备注",
	 * "工作时间", "适用乘客国籍", "除外乘客国籍", "1/2RT佣金计算方式", "出票时限", "出票城市", "是否公布转私有",
	 * "退改费用", "是否适用小团价", "是否适用文件公布运价" };
	 * 
	 * public CommonResult exportExcel(ContextInfo context, String policyIds,
	 * String dir) { if (ObjectUtil.noText(policyIds)) { return
	 * CommonResult.makeFail("请选择至少一条数据！"); } List<CommisionPolicy> policys =
	 * new ArrayList<CommisionPolicy>(); for (String policyId :
	 * policyIds.split(",")) { CommisionPolicy policy =
	 * this.getById4Show(context, Long.valueOf(policyId)); if (policy != null) {
	 * policys.add(policy); } } if (policys == null || policys.isEmpty()) {
	 * return CommonResult.makeFail("数据不存在！"); } String[][] datas = new
	 * String[policys.size()][38]; int index = 0; for (CommisionPolicy policy :
	 * policys) { String[] data = PolicyUtil.getCommisionPolicyDatas(policy);
	 * datas[index++] = data; } String fileName = "返点政策导出" +
	 * DateUtil.toStrDate(new Date()) + ".xlsx"; String path = dir + fileName;
	 * try { ExcelUtil.write("Sheet1", headers, datas, path); } catch (Exception
	 * e) { logger.error("返点政策导出excel错误！", e); return
	 * CommonResult.makeFail("返点政策导出excel错误！"); } return
	 * CommonResult.makeSuccess("导出成功", path); }
	 */

}
